package org.jetnuke.modules.blog;

import org.apache.log4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.VelocityContext;
import org.apache.xmlrpc.XmlRpcServer;
import org.jetnuke.common.ActionForward;
import org.jetnuke.common.IAction;
import org.jetnuke.common.IAdminInfo;
import org.jetnuke.common.IModuleInfo;
import org.jetnuke.common.IUserInfo;
import org.jetnuke.modules.blog.utils.BloggerAPIHandler;
import org.jetnuke.modules.blog.utils.MetaWeblogAPIHandler;
import org.jetnuke.modules.blog.utils.MovableTypeAPIHandler;

public class XmlRPC implements IAction {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(XmlRPC.class);

	private static XmlRpcServer mXmlRpcServer = new XmlRpcServer();
	static {
		mXmlRpcServer.addHandler("blogger", new BloggerAPIHandler());
		mXmlRpcServer.addHandler("metaWeblog", new MetaWeblogAPIHandler());
		mXmlRpcServer.addHandler("mt", new MovableTypeAPIHandler());
	}

	public ActionForward exec(HttpServletRequest request,
			HttpServletResponse response, VelocityContext vc, IModuleInfo info,
			String op, IUserInfo ui, IAdminInfo ai) throws Exception {
		if (logger.isDebugEnabled()) {
			logger
					.debug("exec(HttpServletRequest, HttpServletResponse, VelocityContext, IModuleInfo, String, IUserInfo, IAdminInfo) - start"); //$NON-NLS-1$
		}

		// BufferedReader br=new BufferedReader(new
		// InputStreamReader(request.getInputStream()));
		// String line=null;
		// StringBuffer sb=new StringBuffer();
		// while((line=br.readLine())!=null){
		// sb.append(line);
		// sb.append("\r\n");
		// }
		// String resultStr=sb.toString();
		// byte[] result = mXmlRpcServer.execute(new
		// StringInputStream(resultStr));
		byte[] result = mXmlRpcServer.execute(request.getInputStream());

		response.setContentType("text/xml");
		response.setContentLength(result.length);

		OutputStream output = response.getOutputStream();
		output.write(result);
		output.flush();

		if (logger.isDebugEnabled()) {
			logger
					.debug("exec(HttpServletRequest, HttpServletResponse, VelocityContext, IModuleInfo, String, IUserInfo, IAdminInfo) - end"); //$NON-NLS-1$
		}
		return null;
	}

}

class StringInputStream extends InputStream {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger
			.getLogger(StringInputStream.class);

	private StringReader in;

	public StringInputStream(String source) {
		in = new StringReader(source);
	}

	public int read() throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("read() - start"); //$NON-NLS-1$
		}

		int returnint = in.read();
		if (logger.isDebugEnabled()) {
			logger.debug("read() - end"); //$NON-NLS-1$
		}
		return returnint;
	}

	public void close() throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("close() - start"); //$NON-NLS-1$
		}

		in.close();

		if (logger.isDebugEnabled()) {
			logger.debug("close() - end"); //$NON-NLS-1$
		}
	}

	public synchronized void mark(final int limit) {
		if (logger.isDebugEnabled()) {
			logger.debug("mark(int) - start"); //$NON-NLS-1$
		}

		try {
			in.mark(limit);
		} catch (IOException ioe) {
			logger.error("mark(int)", ioe); //$NON-NLS-1$

			throw new RuntimeException(ioe.getMessage());
		}

		if (logger.isDebugEnabled()) {
			logger.debug("mark(int) - end"); //$NON-NLS-1$
		}
	}

	public synchronized void reset() throws IOException {
		if (logger.isDebugEnabled()) {
			logger.debug("reset() - start"); //$NON-NLS-1$
		}

		in.reset();

		if (logger.isDebugEnabled()) {
			logger.debug("reset() - end"); //$NON-NLS-1$
		}
	}

	public boolean markSupported() {
		if (logger.isDebugEnabled()) {
			logger.debug("markSupported() - start"); //$NON-NLS-1$
		}

		boolean returnboolean = in.markSupported();
		if (logger.isDebugEnabled()) {
			logger.debug("markSupported() - end"); //$NON-NLS-1$
		}
		return returnboolean;
	}
}
